// 请求封装工具
import { message } from 'ant-design-vue'
import { useUserStore } from '@/stores/user'

interface RequestOptions extends RequestInit {
  baseURL?: string
  timeout?: number
  params?: Record<string, any>
  showDebug?: boolean // 是否显示调试信息
}

interface ResponseData<T = any> {
  success: boolean
  data: T
  message?: string
  error?: string
}

// 创建请求实例
class Request {
  private baseURL: string
  private timeout: number
  private headers: Record<string, string>
  private isDev: boolean
  
  constructor() {
    // 从环境变量获取基础URL
    this.baseURL = import.meta.env.VITE_API_BASE_URL || '/api'
    this.timeout = 30000
    this.headers = {
      'Content-Type': 'application/json'
    }
    // 判断是否为开发环境
    this.isDev = import.meta.env.DEV || false
    this.setupInterceptors()
  }
  
  // 设置拦截器
  private setupInterceptors(): void {
    // 这里可以添加更多拦截器配置
  }
  
  // 动态更新baseURL
  public updateBaseURL(newBaseURL: string): void {
    this.baseURL = newBaseURL
    if (this.isDev) {
      console.log('Request baseURL updated to:', newBaseURL)
    }
  }
  
  // 获取token
  private getToken(): string | null {
    return localStorage.getItem('token')
  }
  
  // 构建完整URL
  private buildUrl(url: string, params?: Record<string, any>): string {
    const base = url.startsWith('http') ? url : `${this.baseURL}${url}`
    
    if (!params) return base
    
    const queryString = Object.entries(params)
      .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`)
      .join('&')
    
    return `${base}${base.includes('?') ? '&' : '?'}${queryString}`
  }
  
  // 处理响应
  private async handleResponse<T = any>(response: Response, showDebug: boolean): Promise<T> {
    if (!response.ok) {
      // 处理HTTP错误
      if (response.status === 401) {
        // 处理未授权
        const userStore = useUserStore()
        userStore.logout()
        message.error('登录已过期，请重新登录')
        window.location.href = '/login'
      } else if (response.status === 403) {
        message.error('没有权限访问该资源')
      } else if (response.status >= 500) {
        message.error('服务器错误，请稍后重试')
      }
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    
    try {
      const data = await response.json() as ResponseData<T>
      
      // 开发环境显示响应数据
      if (showDebug) {
        console.log('[Response Data]:', data)
      }
      
      // 处理业务逻辑错误
      if (!data.success) {
        message.error(data.message || data.error || '请求失败')
        throw new Error(data.message || data.error || '请求失败')
      }
      
      return data.data
    } catch (error) {
      if (error instanceof SyntaxError) {
        // 处理JSON解析错误
        if (showDebug) {
          console.error('[JSON Parse Error]:', error)
        }
        throw new Error('Invalid response format')
      }
      throw error
    }
  }
  
  // 核心请求方法
  async request<T = any>(url: string, options: RequestOptions = {}): Promise<T> {
    const {
      method = 'GET',
      headers = {},
      timeout = this.timeout,
      params,
      showDebug = this.isDev, // 默认在开发环境显示调试信息
      ...restOptions
    } = options
    
    // 构建请求头
    const requestHeaders: Record<string, string> = {
      ...this.headers,
      // 确保headers中的值都是字符串类型
      ...Object.fromEntries(
        Object.entries(headers)
          .filter(([_, value]) => typeof value === 'string')
      )
    }
    
    // 添加token
    const token = this.getToken()
    if (token) {
      requestHeaders['Authorization'] = `Bearer ${token}`
    }
    
    // 构建请求配置
    const config: RequestInit = {
      method,
      headers: requestHeaders,
      ...restOptions
    }
    
    // 处理请求体
    if (config.body && typeof config.body === 'object' && !(config.body instanceof FormData)) {
      config.body = JSON.stringify(config.body)
    }
    
    // 构建URL
    const fullUrl = this.buildUrl(url, params)
    
    // 开发环境显示请求信息
    if (showDebug) {
      console.log(`[API Request] ${method} ${fullUrl}`)
      console.log('[Request Headers]:', requestHeaders)
      if (config.body) {
        console.log('[Request Body]:', config.body)
      }
    }
    
    try {
      // 处理超时
      const controller = new AbortController()
      const timeoutId = setTimeout(() => controller.abort(), timeout)
      
      const response = await fetch(fullUrl, {
        ...config,
        signal: controller.signal
      })
      
      clearTimeout(timeoutId)
      
      // 开发环境显示响应状态
      if (showDebug) {
        console.log(`[API Response] ${response.status} ${fullUrl}`)
      }
      
      return await this.handleResponse<T>(response, showDebug)
    } catch (error) {
      if (showDebug) {
        console.error('[API Error]:', error)
      }
      
      if (error instanceof DOMException && error.name === 'AbortError') {
        const timeoutError = new Error('Request timeout')
        if (this.isDev) {
          message.error('请求超时，请检查网络连接')
        }
        throw timeoutError
      }
      
      // 显示网络错误
      if (this.isDev) {
        message.error('网络请求失败，请稍后重试')
      }
      throw error
    }
  }
  
  // 便捷方法
  async get<T = any>(url: string, options: RequestOptions = {}): Promise<T> {
    return this.request<T>(url, { ...options, method: 'GET' })
  }
  
  async post<T = any>(url: string, data?: any, options: RequestOptions = {}): Promise<T> {
    return this.request<T>(url, { ...options, method: 'POST', body: data })
  }
  
  async put<T = any>(url: string, data?: any, options: RequestOptions = {}): Promise<T> {
    return this.request<T>(url, { ...options, method: 'PUT', body: data })
  }
  
  async delete<T = any>(url: string, options: RequestOptions = {}): Promise<T> {
    return this.request<T>(url, { ...options, method: 'DELETE' })
  }
  
  async patch<T = any>(url: string, data?: any, options: RequestOptions = {}): Promise<T> {
    return this.request<T>(url, { ...options, method: 'PATCH', body: data })
  }
}

// 创建并导出请求实例
const request = new Request()

export default request

// 导出类型
export type { RequestOptions, ResponseData }